package com.tensai.study.新特性.JDK8.函数式编程;

import lombok.Data;

import java.util.ArrayList;
import java.util.IntSummaryStatistics;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author Tensai
 */
public class GroupingAndSum {

    public static void main(String[] args) {
        List<Con1> con1List = new ArrayList<>();
        con1List.add(new Con1("a", "1", 1, 1L, 1.0));
        con1List.add(new Con1("a", "1", 2, 3L, 4.0));
        con1List.add(new Con1("a", "1", 3, 5L, 7.0));
        con1List.add(new Con1("b", "1", 1, 1L, 1.0));
        con1List.add(new Con1("b", "1", 2, 3L, 4.0));
        con1List.add(new Con1("c", "1", 1, 1L, 1.0));

//        con1List.stream().map(Con1::get).reduce(new Con2(), Con2::sum);
//        MapAndFlatMap<String, Con2> enusersCollect =
//                con1List.stream().collect(Collectors.groupingBy(Con1:: getT1,
//                        Collectors.reducing(new Con2(),
//                                Con1::get,
//                                Con2::sum)
//                        ));
        Map<String, Map<String, IntSummaryStatistics>> enusersCollect2 =
                con1List.stream().collect(Collectors.groupingBy(Con1:: getT1,
                        Collectors.groupingBy(Con1:: getT2,
                                Collectors.summarizingInt(Con1::getA))));
        enusersCollect2.forEach((k,v)->v.forEach((k2,v2)->
                System.out.println(k + "\t" + k2 + "\t" + v2)));
    }
}

@Data
class Con1{
    String t1;
    String t2;
    Integer a;
    Long b;
    Double c;

    public Con1(String t1, String t2, Integer a, Long b, Double c) {
        this.t1 = t1;
        this.t2 = t2;
        this.a = a;
        this.b = b;
        this.c = c;
    }

    public Con1 get(){
        return this;
    }
}

@Data
class Con2{
    Integer a = 0;
    Long b = 0L;
    Double c = 0.0;

    public Con2 sum(Con1 con1, Con1 con11) {
        return new Con2(con1.getA()+con11.getA(),
                con1.getB() + con11.getB(),
                con1.getC() + con11.getC());
    }
    
    public Con2(List<Con1> con1) {
        this.a = con1.stream().mapToInt(Con1::getA).sum();
        this.b = con1.stream().mapToLong(Con1::getB).sum();
        this.c = con1.stream().mapToDouble(Con1::getC).sum();
    }

    public Con2(Integer a, Long b, Double c) {
        this.a = a;
        this.b = b;
        this.c = c;
    }
}
